package com.xiaoniu.douyinvideo.view

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.os.Build
import android.text.TextUtils
import android.util.AttributeSet
import android.webkit.JavascriptInterface
import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import com.xiaoniu.douyinvideo.apps.VideoApp
import com.xiaoniu.douyinvideo.util.LogUtil
import com.xiaoniu.douyinvideo.util.LogUtil.i
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class KWebView : WebView {
    private var htmlCallback: HtmlCallback? = null
    private var javaScriptLocalObj: InJavaScriptLocalObj? = null

    private var repeatJob: Job? = null

    constructor(context: Context) : super(context) {
        init()
    }

    @SuppressLint("SetJavaScriptEnabled")
    private fun init() {
        // Dom存储支持
        getSettings().setDomStorageEnabled(true)
        // 设置支持javascript
        getSettings().setJavaScriptEnabled(true)
        // 启动缓存
//        getSettings().setAppCacheEnabled(true);
        // 设置缓存模式
        getSettings().setCacheMode(WebSettings.LOAD_DEFAULT)
        // 允许混合模式（http与https）
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW)
        }
        // 获取网页内容的Js调用
        javaScriptLocalObj = InJavaScriptLocalObj(this)
        addJavascriptInterface(javaScriptLocalObj!!, "java_obj")
        setWebViewClient(object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
                view.loadUrl(url)
                return true
            }

            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                super.onPageStarted(view, url, favicon)
            }

            override fun onPageFinished(view: WebView, url: String?) {
                dispose()
                // 定时轮询获取网页内容，直到获取到有效信息
                repeatJob = MainScope().launch {
                    repeat(10) {
                        view.loadUrl(
                            "javascript:window.java_obj.getSource('<head>'+" +
                                    "document.getElementsByTagName('html')[0].innerHTML+'</head>');"
                        )
                        delay(2000)
                    }
                }

                super.onPageFinished(view, url)
            }

            override fun onReceivedError(
                view: WebView?,
                request: WebResourceRequest?,
                error: WebResourceError?
            ) {
                super.onReceivedError(view, request, error)
            }
        })
    }

    fun setVideoApp(app: VideoApp) {
        javaScriptLocalObj!!.setVideoApp(app)
        i("webview开始加载视频网页${app.htmlUrl()}")
        loadUrl(app.htmlUrl()!!)
    }

    /**
     * 取消订阅
     */
    fun dispose() {
        runCatching {
            repeatJob?.cancel()
            repeatJob = null
        }
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        init()
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        init()
    }

    fun setHtmlCallback(htmlCallback: HtmlCallback?) {
        this.htmlCallback = htmlCallback
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        dispose()
    }

    interface HtmlCallback {
        fun videoUrl(urls: Pair<String, String>?)
    }

    /**
     * 逻辑处理
     *
     * @author linzewu
     */
    internal inner class InJavaScriptLocalObj(var webView: KWebView) {
        var app: VideoApp? = null
        private var succeed = false

        fun setVideoApp(app: VideoApp) {
            this.app = app
            succeed = false
        }

        @JavascriptInterface
        fun getSource(html: String) {
            if (succeed) {
                return
            }

            //打印html
            LogUtil.i("html-------------------\n")
            val size = html.length / 300
            for (i in 0..<size) {
                if (i != size - 1) {
                    LogUtil.i(html.substring(i * 300, (i + 1) * 300))
                } else {
                    LogUtil.i(html.substring(i * 300))
                }
            }
            LogUtil.i("html---------------------\n")


            val videoPair = app!!.parseHtml(html) ?: return
            i("从html中解析出视频地址：${videoPair.first}")

            succeed = true
            // 主线程运行取消
            MainScope().launch {
                webView.dispose()
            }
            // 回调
            if (htmlCallback != null) {
                htmlCallback!!.videoUrl(videoPair)
            }
        }
    }
}